home *** CD-ROM | disk | FTP | other *** search
- /* kcapApp */
- /* demonstration keyboard drawing from KCAP resource */
-
- /* Greg Robbins 12/91 */
-
- /* includes code stolen from Bo3b's TubeTest */
-
- /* version 1.1, 2/92: uses RGetResource rather than GetResource for KCAP;
- gets KCHR number from script manager */
-
- /* version 1.2, 2/92: adds menu of KCAP IDs, displays virtual keycodes */
-
-
- #include <Types.h>
- #include <Memory.h>
- #include <Quickdraw.h>
- #include <Fonts.h>
- #include <Events.h>
- #include <Menus.h>
- #include <Windows.h>
- #include <Resources.h>
- #include <Dialogs.h>
- #include <Desk.h>
- #include <Scrap.h>
- #include <OSUtils.h>
- #include <ToolUtils.h>
- #include <SegLoad.h>
- #include <SysEqu.h>
- #include <Script.h>
- #include <Packages.h>
- #include <String.h>
- #include <Strings.h>
- #include <Folders.h>
-
- /* Constants */
- #define appleID 1000 /* resource IDs/menu IDs for Apple, */
- #define fileID 1001 /* File and */
- #define editID 1002 /* Edit menus */
- #define displayID 1003
-
- #define appleM 0 /* Index for each menu in myMenus (array of menu handles) */
- #define fileM 1
- #define editM 2
- #define displayM 3
-
- #define menuCount 4 /* Total number of menus */
-
- #define windowID 1000 /* Resource ID for main window */
- #define aboutMeDLOG 1000 /* And Resource ID for About box dialog. */
-
- #define quitItem 1 /* Quit in the File menu */
-
- #define aboutMeCommand 1 /* Menu item in apple menu for About */
-
-
- /* Globals */
- MenuHandle myMenus[menuCount];
- Rect dragRect;
- Boolean doneFlag;
- EventRecord myEvent;
- WindowPtr myWindow, whichWindow;
- char theChar;
-
- Boolean gKeycodesFlag = false;
- short gKcapNum, gCurrDisplayItem;
-
- void SetUpMenus();
- void DoCommand(long int mResult);
- void DrawKeyCaps(short modifiers, short kcharNum, short kcapNum, Boolean keycodesFlag);
-
-
- main()
- {
- Str255 tempStr, tempStr2;
- StringHandle tempStrHandle;
-
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
-
- SetRect(&dragRect, 4, 24, qd.screenBits.bounds.right - 4, qd.screenBits.bounds.bottom - 4);
- doneFlag = false; /* flag to detect when Quit command is chosen */
-
- myWindow = GetNewWindow(windowID, nil, (WindowPtr) -1);
- SetPort(myWindow);
-
- SetUpMenus();
-
- /*
- ** Main Event Loop
- */
- do {
- if (WaitNextEvent(everyEvent, &myEvent, 600, nil)) {
- switch (myEvent.what) { /* case on event type */
-
- case mouseDown:
- switch (FindWindow(myEvent.where, &whichWindow)) {
-
- case inSysWindow: /* desk accessory window: call Desk Manager to handle it */
- SystemClick(&myEvent, whichWindow);
- break;
-
- case inMenuBar: /* Menu bar: learn which command, then execute it. */
- DoCommand(MenuSelect(myEvent.where));
- break;
-
- case inDrag: /* title bar: call Window Manager to drag */
- DragWindow(whichWindow, myEvent.where, &dragRect);
- break;
-
- case inContent: /* body of application window: */
- if (whichWindow != FrontWindow())
- SelectWindow(whichWindow); /* and make it active if not */
- break;
- }
- break;
-
- case updateEvt: /* Update the window. */
- if ((WindowPtr) myEvent.message == myWindow) {
- BeginUpdate((WindowPtr) myEvent.message);
-
- /* draw keyboard using current keyboard modifiers,
- current KCHR, current keyboard KCAP
-
- see Tech Note 263 for a better way to get the
- KCHR data under System 7 */
-
- DrawKeyCaps(myEvent.modifiers,
- GetScript(GetEnvirons(smKeyScript), smScriptKeys),
- gKcapNum, gKeycodesFlag);
-
- EndUpdate((WindowPtr) myEvent.message);
-
- /* set window title */
- NumToString(gKcapNum, tempStr);
-
- if (gKeycodesFlag) {
- /* set window title to "Virtual Keycodes for KCAP ID _" */
- tempStrHandle = GetString(128);
- if (tempStrHandle) {
- p2cstr(*tempStrHandle);
- strcpy(tempStr2, *tempStrHandle);
- strcat(tempStr2, p2cstr(tempStr));
- SetWTitle(myWindow, c2pstr(tempStr2));
- ReleaseResource(tempStrHandle);
- }
- }
- else {
- tempStrHandle = GetString(129);
- if (tempStrHandle) {
-
- /* set window title to "Key Labels for KCAP ID _ and KCHR _" */
- p2cstr(*tempStrHandle);
- strcpy(tempStr2, *tempStrHandle); /* string */
- strcat(tempStr2, p2cstr(tempStr)); /* KCAP # */
- ReleaseResource(tempStrHandle);
- tempStrHandle = GetString(130);
- if (tempStrHandle) {
- p2cstr(*tempStrHandle);
- strcat(tempStr2, *tempStrHandle); /* string */
-
- /* get current KCHR number */
- NumToString(GetScript(GetEnvirons(smKeyScript), smScriptKeys), tempStr);
- strcat(tempStr2, p2cstr(tempStr)); /* KCHR # */
- SetWTitle(myWindow, c2pstr(tempStr2));
- ReleaseResource(tempStrHandle);
- }
- }
- }
- }
- break;
-
- case keyDown:
- case autoKey: /* key pressed once or held down to repeat */
- if (myWindow == FrontWindow()) {
- theChar = (myEvent.message & charCodeMask); /* get the char */
- /*
- ** If Command key down, do it as a Menu Command.
- */
- if (myEvent.modifiers & cmdKey)
- DoCommand(MenuKey(theChar));
- else {
- EraseRect(&myWindow->portRect);
- InvalRect(&myWindow->portRect);
- }
- }
- break;
-
- }
- }
-
- } while (!doneFlag);
-
- DisposeWindow (myWindow);
- }
-
-
- void SetUpMenus()
- {
- short i, kcapMaxCount, tempInt;
- Handle kcapHandle;
- Str255 tempStr, kcapStr;
- ResType tempResType;
-
- myMenus[appleM] = GetMenu(appleID); /* read Apple menu from resource file */
- AddResMenu(myMenus[appleM], 'DRVR'); /* add desk accessory names to Apple menu */
- myMenus[fileM] = GetMenu(fileID); /* read file menu from resource file */
- myMenus[editM] = GetMenu(editID); /* read edit menu from resource file */
- DisableItem(myMenus[editM], 0);
- myMenus[displayM] = GetMenu(displayID); /* read display menu from resource file */
-
- /* add IDs of KCAP resources to display menu */
- gKcapNum = *((char *) KbdType); /* KCAP ID of current keyboard */
-
- *(short *)RomMapInsert = 0x0100; /* use ROM resources, SetResLoad(false) */
-
- kcapMaxCount = CountResources('KCAP');
- if (kcapMaxCount > 0) AppendMenu(myMenus[displayM], "\p(-!");
-
- /* add KCAP menu items */
- for (i = 1; i <= kcapMaxCount; i++) {
- *(short *)RomMapInsert = 0x0100;
- kcapHandle = GetIndResource('KCAP', i);
- if (kcapHandle) {
- GetResInfo(kcapHandle, &tempInt, &tempResType, tempStr);
- NumToString(tempInt, tempStr);
- AppendMenu(myMenus[displayM],
- c2pstr(strcat(strcpy(kcapStr, "KCAP "), p2cstr(tempStr))));
- ReleaseResource(kcapHandle);
-
- if (tempInt == gKcapNum) {
- CheckItem(myMenus[displayM], i+2, true);
- gCurrDisplayItem = i+2;
- }
- }
- }
- gKeycodesFlag = false; /* not displaying keycodes on keys initially */
- CheckItem(myMenus[displayM], 1, !gKeycodesFlag); /* mark that key labels are displayed */
-
- for (i = 0; i < menuCount; i++)
- InsertMenu(myMenus[i], 0); /* install menus in menu bar */
-
-
- DrawMenuBar(); /* and draw menu bar */
- }
-
-
- void ShowAboutMeDialog()
- {
- DialogPtr theDialog;
- short itemHit;
-
- theDialog = GetNewDialog(aboutMeDLOG, nil, (WindowPtr) -1);
- ModalDialog(nil, &itemHit);
- DisposDialog(theDialog);
- }
-
-
- /* DrawKeyCaps draws the key caps, given a set of
- modifiers (in the high byte of the short) and
- KCHR and KCAP resource IDs, using the current pen in
- the current GrafPort
-
- if keycodesFlag is true, the virtual keycodes are drawn
- rather than the key labels.
-
- kcapPtr just bounces along the resource data as we
- parse it
- */
-
- /* see resource type definition on p. 14-101 of IM VI */
-
- void DrawKeyCaps(short modifiers, short kchrNum, short kcapNum, Boolean keycodesFlag)
- {
- typedef struct {
- char modifierMask;
- char keyCode;
- short deltaV;
- short deltaH;
- } KeyEntryRec;
-
- #define SHAPEMAXPTS 10 /* hopefully, fewer than 10 points per shape */
-
- Rect tempRect;
- Point penPoint, currPoint, swapPoint;
- Point shapePoint[SHAPEMAXPTS];
- Handle kcapResHandle;
- Ptr kcapPtr;
-
- KeyEntryRec thisKeyEntryRec;
- short mainIndex, shapeIndex, keyIndex, shapeTotal, shapeCount;
- short modifiedKeyCode;
-
- FontInfo theFontInfo;
- short fontHeight;
- Point charLoc;
- char theChar;
-
- RgnHandle keyshapeRgnHandle;
-
- Handle kchrResHandle;
- long state;
-
- Str255 keycodeStr;
- short saveTextSize;
-
- GetFontInfo(&theFontInfo);
- fontHeight = theFontInfo.ascent + theFontInfo.descent;
- saveTextSize = myWindow->txSize;
-
- kchrResHandle = RGetResource('KCHR', kchrNum);
- if (ResError() == noErr && kchrResHandle != nil) {
- state = 0;
-
- kcapResHandle = RGetResource('KCAP', kcapNum);
- if (ResError() == noErr && kcapResHandle != nil) {
-
- keyshapeRgnHandle = NewRgn();
-
- MoveHHi(kcapResHandle);
- HLock(kcapResHandle);
- kcapPtr = *kcapResHandle;
-
- /* draw boundary from origin */
- tempRect = *((Rect *) kcapPtr);
- OffsetRect(&tempRect, - tempRect.left, -tempRect.top);
- EraseRect(&tempRect);
- FrameRect(&tempRect);
- kcapPtr += sizeof(Rect);
-
- /* draw textedit area */
- tempRect = *((Rect *) kcapPtr);
- FrameRect(&tempRect);
- kcapPtr += sizeof(Rect);
-
- /* loop through main array */
- mainIndex = *((short *) kcapPtr);
- kcapPtr += sizeof(short);
- for ( ; mainIndex>0; mainIndex--) {
-
- /* loop through shape array - build array of points for this shape */
- shapeIndex = *((short *) kcapPtr);
- kcapPtr += sizeof(short);
-
- shapeTotal = (shapeIndex < SHAPEMAXPTS ? shapeIndex + 1 : SHAPEMAXPTS);
- for (shapeCount=0; shapeIndex>-1; shapeIndex--, shapeCount++) {
- shapePoint[shapeCount] = *((Point *) kcapPtr);
- kcapPtr += sizeof(Point);
- }
-
- /* start drawing keys of this shape from 0,0 */
- MoveTo(0,0);
-
- /* loop through key array */
- keyIndex = *((short *) kcapPtr);
- kcapPtr += sizeof(short);
- for ( ; keyIndex>-1; keyIndex--) {
-
- /* get modifier mask, keyCode, and offset from previous key */
- thisKeyEntryRec = *((KeyEntryRec *) kcapPtr);
- kcapPtr += sizeof(KeyEntryRec);
-
- /* move the pen to the start of the key */
- Move(thisKeyEntryRec.deltaH, thisKeyEntryRec.deltaV);
-
- /* draw the key, composed of one or more rects */
- SetPt(&currPoint, 0, 0);
- OpenRgn();
-
- for (shapeCount=0, shapeIndex=shapeTotal; shapeIndex;
- shapeIndex--, shapeCount++) {
-
- /* set the rect, then reverse coordinates if necessary
- to ensure it is not empty */
- SetRect(&tempRect, currPoint.h, currPoint.v,
- shapePoint[shapeCount].h, shapePoint[shapeCount].v);
-
- if (tempRect.top > tempRect.bottom) {
- swapPoint.v = tempRect.top;
- tempRect.top = tempRect.bottom;
- tempRect.bottom = swapPoint.v;
- }
- if (tempRect.left > tempRect.right) {
- swapPoint.h = tempRect.left;
- tempRect.left = tempRect.right;
- tempRect.right = swapPoint.h;
- }
-
- /* move the rect to the pen location and add it to the region */
- currPoint = shapePoint[shapeCount];
- GetPen(&penPoint);
- OffsetRect(&tempRect, penPoint.h, penPoint.v);
- FrameRect(&tempRect);
- }
-
- /* draw the key frame */
- CloseRgn(keyshapeRgnHandle);
- FrameRgn(keyshapeRgnHandle);
- SetEmptyRgn(keyshapeRgnHandle);
-
- /* convert the keyCode to a character code */
- /* mask out high bit of keyCode and add masked modifiers;
- KeyTrans stroke bit taken from modifier parameter */
-
- if (thisKeyEntryRec.keyCode & 0x80)
- modifiers &= (((short) thisKeyEntryRec.modifierMask) << 8);
- else modifiers |= (((short) thisKeyEntryRec.modifierMask) << 8);
-
- modifiedKeyCode =
- ((thisKeyEntryRec.keyCode & 0x007F) | (modifiers & 0xFF80));
-
- theChar = KeyTrans(*kchrResHandle, modifiedKeyCode, &state);
-
- if (!keycodesFlag) {
- /* center and draw the character */
- charLoc.v =
- ((tempRect.top + tempRect.bottom) / 2) - (fontHeight / 2);
- charLoc.v += theFontInfo.ascent;
- charLoc.h =
- ((tempRect.left + tempRect.right) / 2) - (CharWidth(theChar) / 2);
- MoveTo(charLoc.h, charLoc.v);
- DrawChar(theChar);
- } else {
- /* draw the virtual keycode instead of the key label */
- TextSize(9);
- NumToString(modifiedKeyCode & 0x7F, keycodeStr);
- charLoc.v =
- ((tempRect.top + tempRect.bottom) / 2) - (fontHeight / 2);
- charLoc.v += theFontInfo.ascent;
- charLoc.h =
- ((tempRect.left + tempRect.right) / 2) - (StringWidth(keycodeStr) / 2);
- MoveTo(charLoc.h, charLoc.v);
- DrawString(keycodeStr);
- }
-
- /* reposition pen for next key */
- MoveTo(penPoint.h, penPoint.v);
- }
- }
- HUnlock(kcapResHandle);
- DisposeRgn(keyshapeRgnHandle);
-
- /* release the KCAP and KCHR unless they're System resources */
- if (HomeResFile(kcapResHandle) > 1) ReleaseResource(kcapResHandle);
- }
- if (HomeResFile(kchrResHandle) > 1) ReleaseResource(kchrResHandle);
-
- TextSize(saveTextSize);
- }
- }
-
-
- void DoCommand(long int mResult)
- {
- short theItem, /* menu item number from mResult low-order word */
- theMenu; /* menu number from mResult high-order word */
- Str255 name; /* desk accessory name */
- int tempInt;
- ResType tempResType;
- Str255 tempStr;
-
- Handle kcapHandle;
- theItem = LoWord(mResult); /* call Toolbox Utility routines to */
- theMenu = HiWord(mResult); /* set menu item number and menu */
-
- switch (theMenu) { /* switch on menu ID */
-
- case appleID:
- if (theItem == aboutMeCommand)
- ShowAboutMeDialog();
- else {
- GetItem(myMenus[appleM], theItem, name);
- tempInt = OpenDeskAcc(name);
- SetPort(myWindow);
- }
- break;
-
- case fileID:
- if (theItem == quitItem)
- doneFlag = true;
- break;
-
- case editID:
- if (!SystemEdit(theItem - 1)) { /* Pass the command on to the Desk Manager. */
- ; /* do nothing */
- };
- break;
-
- case displayID:
-
- if (gCurrDisplayItem != theItem) {
-
- if (theItem == 1) {
-
- /* display key labels */
- gKeycodesFlag = !gKeycodesFlag;
- CheckItem(myMenus[displayM], 1, !gKeycodesFlag);
-
- } else {
-
- *(short *)RomMapInsert = 0x0100; /* use ROM resources, SetResLoad(false) */
- kcapHandle = GetIndResource('KCAP', theItem - 2);
-
- if (kcapHandle) {
- /* find the ID of the chosen KCAP */
- GetResInfo(kcapHandle, &gKcapNum, &tempResType, tempStr);
- ReleaseResource(kcapHandle);
-
- CheckItem(myMenus[displayM], gCurrDisplayItem, false);
- CheckItem(myMenus[displayM], theItem, true);
-
- gCurrDisplayItem = theItem;
- }
- }
-
-
- EraseRect(&myWindow->portRect);
- InvalRect(&myWindow->portRect);
- }
-
- break;
- }
-
- HiliteMenu(0); /* Unhighlight menu title */
- /* (highlighted by MenuSelect) */
- }
-